package cn.thoughtworks.school.services;

import cn.thoughtworks.school.entities.Assignment;
import cn.thoughtworks.school.entities.Task;
import cn.thoughtworks.school.repositories.AssignmentDiffRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.thoughtworks.school.entities.Operation.COPY;
import static cn.thoughtworks.school.entities.Operation.CREATE;

@Service
public class AssignmentDiffService {
    @Autowired
    private AssignmentDiffRepository assignmentDiffRepository;

    public void updateAssignmentsNotification(List<Map> data) {
        List<Assignment> assignments = data.stream()
            .map(Assignment::build)
            .collect(Collectors.toList());
        assignments.forEach(this::updateAssignmentFromId);
        assignmentDiffRepository.saveAll(assignments);
    }

    private void updateAssignmentFromId(Assignment assignment) {
        if (Objects.equals(CREATE, assignment.getOperation()) || Objects.equals(COPY, assignment.getOperation())) {
            return;
        }
        Long fromId = assignmentDiffRepository.findFirst1ByAssignmentIdOrderByIdDesc(assignment.getAssignmentId()).getFromId();
        assignment.setFromId(fromId);
    }

    public List<Assignment> getLatestAssignmentByTasksId(List<Long> ids) {
        return ids.isEmpty()
            ? new ArrayList<>()
            : assignmentDiffRepository.findFirst1ByIdAndProgramIdInOrderByTasksIdDesc(ids);
    }

    public void fillLatestAssignmentsToTasks(List<Task> tasks) {
        List<Assignment> assignments = getLatestAssignmentByTasksId(tasks.stream().map(Task::getTaskId).collect(Collectors.toList()));
        fill(tasks, assignments);
    }

    private void fill(List<Task> tasks, List<Assignment> assignments) {
        tasks.forEach(task -> {
            List<Assignment> foundAssignments = assignments.stream().filter(assignment -> assignment.getTaskId().equals(task.getTaskId()))
                .collect(Collectors.toList());
            task.setAssignments(foundAssignments);
        });
    }

    public void fillAssignmentsToTasks(List<Task> tasks) {
        List<Assignment> assignments = getLatestAssignmentByTasksId(tasks.stream().map(Task::getTaskId).collect(Collectors.toList()));
        fill(tasks, assignments);
    }
}
